﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Interactivity;
using System.Windows.Threading;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Shell;

namespace Store.WP7.Framework.Interactions
{
    public class SystrayBehavior : Behavior<PhoneApplicationPage>
    {
        #region SystrayOpacity (DependencyProperty)

        /// <summary>
        /// Opacity of the system tray
        /// </summary>
        public double? SystrayOpacity
        {
            get { return (double?)GetValue(SystrayOpacityProperty); }
            set { SetValue(SystrayOpacityProperty, value); }
        }

        public static readonly DependencyProperty SystrayOpacityProperty =
            DependencyProperty.Register("SystrayOpacity", typeof(double?), typeof(SystrayBehavior),
              new PropertyMetadata(null));

        #endregion

        #region Timer (DependencyProperty)

        /// <summary>
        /// Timer for the systray to disappear (in seconds)
        /// </summary>
        public double Timer
        {
            get { return (double)GetValue(TimerProperty); }
            set { SetValue(TimerProperty, value); }
        }

        public static readonly DependencyProperty TimerProperty =
            DependencyProperty.Register("Timer", typeof(double), typeof(SystrayBehavior),
              new PropertyMetadata(3.0));

        #endregion


        #region IsBusy (DependencyProperty)

        /// <summary>
        /// A description of the property.
        /// </summary>
        public bool IsBusy
        {
            get { return (bool)GetValue(IsBusyProperty); }
            set { SetValue(IsBusyProperty, value); }
        }
        public static readonly DependencyProperty IsBusyProperty =
            DependencyProperty.Register("IsBusy", typeof(bool), typeof(SystrayBehavior),
            new PropertyMetadata(false, new PropertyChangedCallback(OnIsBusyChanged)));

        private static void OnIsBusyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ((SystrayBehavior)d).OnIsBusyChanged();
        }

        #endregion

        #region BusyMessage (DependencyProperty)

        /// <summary>
        /// A description of the property.
        /// </summary>
        public string BusyMessage
        {
            get { return (string)GetValue(BusyMessageProperty); }
            set { SetValue(BusyMessageProperty, value); }
        }
        public static readonly DependencyProperty BusyMessageProperty =
            DependencyProperty.Register("BusyMessage", typeof(string), typeof(SystrayBehavior),
            new PropertyMetadata(null, new PropertyChangedCallback(OnBusyMessageChanged)));

        private static void OnBusyMessageChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ((SystrayBehavior)d).OnBusyMessageChanged();
        }

        #endregion

        private ProgressIndicator _progressIndicator;

        public SystrayBehavior()
        {
            _progressIndicator = new ProgressIndicator();
            _progressIndicator.IsIndeterminate = true;
        }

        protected override void OnAttached()
        {
            base.OnAttached();

            AssociatedObject.Loaded += AssociatedObject_Loaded;

            AssociatedObject.MouseLeftButtonDown += AssociatedObject_MouseLeftButtonUp;
        }

        void AssociatedObject_Loaded(object sender, RoutedEventArgs e)
        {
            SystemTray.IsVisible = false;
            SystemTray.ProgressIndicator = _progressIndicator;

            OnIsBusyChanged();
        }

        protected override void OnDetaching()
        {
            AssociatedObject.Loaded -= AssociatedObject_Loaded;
            AssociatedObject.MouseLeftButtonDown -= AssociatedObject_MouseLeftButtonUp;
            base.OnDetaching();
        }

        private DispatcherTimer timer;

        void AssociatedObject_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            if (e.GetPosition((UIElement)sender).Y <= 32)
            {
                ShowSystray();

                timer = new DispatcherTimer() { Interval = TimeSpan.FromSeconds(Timer) };
                timer.Tick += new EventHandler(timer_Tick);
                timer.Start();
            }
        }

        private void ShowSystray()
        {
            if (SystrayOpacity.HasValue)
                SystemTray.Opacity = SystrayOpacity.Value;

            SystemTray.IsVisible = true;
        }

        private void HideSystray()
        {
            SystemTray.IsVisible = false;
        }

        void timer_Tick(object sender, EventArgs e)
        {
            timer.Stop();
            timer.Tick -= new EventHandler(timer_Tick);

            Deployment.Current.Dispatcher.BeginInvoke(() =>
            {
                HideSystray();
            });
        }

        protected void OnIsBusyChanged()
        {
            _progressIndicator.IsVisible = IsBusy;

            if (timer != null)
                timer.Stop();

            if (IsBusy)
                ShowSystray();
            else
                HideSystray();
        }

        protected void OnBusyMessageChanged()
        {
            _progressIndicator.Text = BusyMessage;
        }

        bool previousState;
        void Associated_ObjectSizeChanged(object sender, SizeChangedEventArgs e)
        {
            if (previousState == SystemTray.IsVisible)
                return;

            previousState = SystemTray.IsVisible;

            if (SystemTray.IsVisible)
                AssociatedObject.Margin = new Thickness(0, -32, 0, 0);
            else
                AssociatedObject.Margin = new Thickness(0, 0, 0, 0);
        }

    }
}
